////////////////////////////
/** \file OzZtypes.h
 *	OzZ Controls Types
 *	Include this directly for a plugin-project!\n
 *	Include OzZcontrols.h to your application-project instead\n
 *	(c) Copyright by Daniel Bulla 2006
 *	\author Daniel 'OzZ' Bulla
 */
#pragma once

#ifndef NULL
#ifdef __cplusplus
#define NULL	0
#else
#define NULL    ((void*)0)
#endif
#endif

#ifndef MAX_PATH
#define MAX_PATH 260
#endif

#ifndef PROFILE_BLOCK
#define PROFILE_BLOCK(text)
#endif

namespace oc
{

typedef void*			HANDLE;
typedef unsigned char	BYTE;
typedef unsigned short	WORD;
typedef unsigned long	DWORD;
typedef unsigned int	UINT;

#define MAKEHOOK(id) {#id} // maybe make the hooks beeing numbers and be looked up for by a #define


typedef	float Coord1D;

typedef const char* HOOKID;
typedef void*		PARAMETER;

/// used to communicate between the modules
union TransData
{
	DWORD	dw;
	void*	p;
	const char* str;
};

/// holds a advanced coordinate
/** It is used to store cordinates in a polar or cartesian coordinate system.
 *	This feature should convince and animate useres to produce more complex projects which are unique
 *	\todo ask renderplugin to give raw-data(this struct) or absolute x y values to it
 */

struct Coord2D_ex
{
	float xr;		///< x value or radius
	float ya;		///< y value or angle
	char ipret;		///< interpretation: cartesian or polar ?
	char ipretX;	///< interpretation for xr: absolute or relative
	char ipretY;	///< interpretation for ya: absolute or relative
};
/// holds a simple cartesian coordiante
/** For the most visalizers this shold result in a slightly faster calculation
 */
struct Coord2D_si
{
	Coord2D_si(){}
	Coord2D_si(Coord1D a, Coord1D b):x(a), y(b){}
	Coord1D x;
	Coord1D y;
};

/// Holds information about a color plus alpha.
struct Color
{
	float r;	///< color red component		
	float g;	///< color green component
	float b;	///< color blua comonent
	float a;	///< alpha value
};

/// Gives information about a possible point versus element Collision \sa AdvancedCollisionInfo
struct CollisionInfo
{
	bool	over;					///< indicates, if a point is definitly over an element!
	Color	color;					///< if there is a collision, this is the color of the element (and how "visible" is the elem at the point stored in alpha)! It is not the total-color of the screen at the point's position
};

struct Element;
/// Gives information about a occurred point versus element Collision \sa CollisionInfo
struct AdvancedCollisionInfo
{

	Color	color;					///< if there is a collision, this is the color of the element (and how "visible" is the elem at the point stored in alpha)! It is not the total-color of the screen at the point's position
	const Element* pElem;			///< 
	AdvancedCollisionInfo* pNext;	///< pointer to another AdvancedCollisionInfo, that refers to the collision between the point and an element, that lays lower! The lower element has not to be a child of \var pElem.
};
///< \todo: destructor for after Points over which.



/// Contains a ready-to-use point, that can be rendered (among others as part of a line).
/** Additionally it can be set to a object, it should automatically set to the right slot, by specifying the desired index
 */
struct RenderPoint
{
	int			index;			///< Index inside an object
	Coord2D_si	pos;			///< it's coordinates
	Color*		pColor;			///< it's color
	Coord1D		thickness;		///< it's thickness
	short		interpolation;	///< for lines: how should the path, color and thickness between this and the point with index = this.index+1 be interpolated?
};

/// indicates the type of an element
enum eType
{
	TYPE_IMAGE	=	1,
	TYPE_LINE	=	2,
	TYPE_TEXT	=	3,
	TYPE_CONTAINER	=	4
};

/// defines the "quality" and smoothing options for scaled and rotated drawings
enum eFilter
{
	FILTER_POINT = 0,
	FILTER_BILINEAR = 1,
	FILTER_TRILINEAR = 2
};

enum eBlend
{
	BLEND_ZERO,
	BLEND_ONE,
	BLEND_SRCCOLOR,
	BLEND_INVSRCCOLOR,
	BLEND_SRCALPHA,
	BLEND_INVSRCALPHA,
	BLEND_DESTALPHA,
	BLEND_INVDESTALPHA,
	BLEND_DESTCOLOR,
	BLEND_INVDESTCOLOR
};
///// "Texturingmode"
//enum eMode
//{
//	MODE_WRAP	=	1,
//	MODE_MIRROR	=	2,
//	MODE_CLAMP	=	3,
//	MODE_BORDER	=	4
//};

class CostumeData;		///< a structure defined by the plugin, where it can store data to access later
class CostumeMat;		///< same as CostumeData, but used for positions, scale and angle
						/**< This is needed seperately for quick transformations etc. ...
						 */

/// A logical, well defined element.
/**	Contains all the data that is needed by the user. The members define
 *	the look and behaviour of the element. This is also the structure, that is passed
 *	to the visalizator, so there are some privat members needed for fast-transformation
 */
struct Element;
struct ElementPaper
{
	ElementPaper(){};
	Element*			pParent;
	Element*			pNext;
	Element*			pPrev;
	Element*			pFirstChild;

	bool				render;				///< visibility
	eType				type;				///< image ? line ? font ? ... ?
	HANDLE				handle;				///< handle to a texture/font/line-object
//	float				u1, v1;				///< tex coords
//	float				u2, v2;				///< tex coords
	eFilter				filter;				///< texturefilter, POINT or SMOOTH ?
//	Color*				colorKey;			///< \deprecated transparency color
	Color*				color;				///< color containing an alpha value, transparence
//	eIMode				mode;				///< How to interpret UV coords ? What to do if the UV coordinates are out of range ?
//	DWORD				pattern;			///< for lines. dotted or anyhow special? \todo remove?
//	float				patternScale;		///< pattern's size	\todo remove?
	bool				antialias;			///< is the [line] antialiased ?
	Element*			alphamap;			///< handle to an Element, used as an alphamap
	eBlend				blendSrc;			///< blending FX
	eBlend				blendDest;			///< blending FX
	const char*			string;				///< place for text

		// todo: make it be pointer and struct, that tells the GUI what the pointer will point at
		// gurumeditation: Coord2D_ex needs to be anywhere to be updated all the time, why not here ?
		//- maybe add coordsys dependencys to let it only update when coordsys updates (if relative)

	Coord2D_si			pos;				///< the element's position
	Coord2D_si			size;				///< the element's size
	Coord2D_si			center;				///< the center around which rotation effects
	// auch uv ?!
	float				rot;				///< the angle the element is rotated around it's center

	float				detail;				///< defines the rendering-quality of the element; shouldn't affect its behaviuor

	const UINT			GetTextWidth() const {return uiTextWidth;};
	const UINT			GetTextHeight() const {return uiTextHeight;};
private:
	friend class CVisualizator;				///< The visualizator will acces these members for rendering
// costume:
	CostumeData*		pCostume;			///< \sa CostumeData
	CostumeMat*			pPosAngleSize;		///< contains information about size, position, the center and rotation, calculated by the data given via public members
											/**<	(calculated per Add/SubPosAngle, invoked by oc, calculated by plugin)
											 */

// filled by plugin:
	UINT		uiTextWidth;				///< have to be set by plugin: the width in [units(-pixels or relative coord))] the text in 'string' has with current rendering-parameters; if string is 0 this member is ignored.
	UINT		uiTextHeight;				///< \sa uiTextWidth;
};

//typedef void* ElementPaper::* MPOINTER;
typedef unsigned long MPOINTER;
/// @name ElementPaper-Member Pointer
/// @{
//#define M_RENDER (ElementPaper::(*render))
//#define M_TYPE ElementPaper::(*type)
//#define M_HANDLE ElementPaper::(*handle)
//#define M_FILTER ElementPaper::(*filter)
//#define M_COLOR ElementPaper::(*color)
//#define M_ANTIALIAS ElementPaper::(*antialias)
//#define M_ALPHAMAP ElementPaper::(*alphamap)
//#define M_BLENDSRC ElementPaper::(*blendSrc)
//#define M_BLENDDEST ElementPaper::(*blendDest)
//#define M_STRING ElementPaper::(*string)
//#define M_POS ElementPaper::(*pos) // not important wether x or y...
//#define M_SIZE ElementPaper::(*size)
//#define M_CENTER ElementPaper::(*center)
//#define M_ROT ElementPaper::(*rot)
//#define M_DETAIL ElementPaper::(*detail)
//#define M_POSANGLESIZE ((unsigned long)(&ElementPaper::pPosAngleSize))
//#define M_UNAVALIABLE ElementPaper::(*pCostume)

#define M_RENDER		1
#define M_TYPE			2
#define M_HANDLE		3
#define M_FILTER		4
#define M_COLOR			5
#define M_ANTIALIAS		6
#define M_ALPHAMAP		7
#define M_BLENDSRC		8
#define M_BLENDDEST		9
#define M_STRING		10
#define M_POS			11 // not important whether x or y...
#define M_SIZE			12
#define M_CENTER		13
#define M_ROT			14
#define M_DETAIL		15
#define M_POSANGLESIZE	16
#define M_UNAVALIABLE	17

/// @}
/*
typedef ElementPaper::(*render) M_RENDER;
typedef ElementPaper::(*type) M_TYPE;
typedef ElementPaper::(*handle) M_HANDLE;
typedef ElementPaper::(*filter) M_FILTER;
typedef ElementPaper::(*color) M_COLOR;
typedef ElementPaper::(*antialias) M_ANTIALIAS;
typedef ElementPaper::(*alphamap) M_ALPHAMAP;
typedef ElementPaper::(*blendSrc) M_BLENDSRC;
typedef ElementPaper::(*blendDest) M_BLENDDEST;
typedef ElementPaper::(*string)	M_STRING;
typedef ElementPaper::(*pos)	M_POS; // not important wether x or y...
typedef ElementPaper::(*size)	M_SIZE;
typedef ElementPaper::(*center)	M_CENTER;
typedef ElementPaper::(*rot)	M_ROT;
typedef ElementPaper::(*detail)	M_DETAIL;
typedef ElementPaper::(*pPosAngleSize)	M_POSANGLESIZE;
typedef ElementPaper::(*pCostume) M_UNAVALIABLE;

*/
} //namespace oc